from anole.utils.patterns.Singleton import Singleton
from anole.core.checkpoint import CheckPointManager
from anole.core.frontier import BaseURLSupplier
from anole.core.crawlhandler import CrawlHandler
from anole.core.fetcher import  Fetcher
from anole.core.crawler import  Crawler
from anole.core.processormgr import ProcessorMgr
import threading
	
class AnoleFactory(Singleton):
#do the ugly creation and init work for anole
#we assume the init work is done only at the start up of anole
#and the multi-threads sync work is done based on this assumption

	def create_crawler(self,config):
		c=self._create_components(config)
		crawler=self._create_crawler(c)

		#when  crawler is created ,we create pm and user-defined processor
		pm=self._create_pm(c,crawler)
		handler=c['HANDLER']
		self.__create_processors(pm,handler)
		
		#all are ok,load last check ponit
		if config.has_key('CKP_TIME') and config['CKP_TIME']!=0:
			cpm=c['CPM']
			cpm.load()

		return crawler

	def _create_crawler(self,c):
		config=c['CONFIG']
		try:
			ckpTime=config['CKP_TIME']
			crawler=Crawler(c,ckpTime)	
		except KeyError:
			crawler=Crawler(c)	

		return crawler
		

	def _create_components(self,config):
		#create common services
		cpm=CheckPointManager()
		
		#create components
		usp=self._create_usp(config)
		cpm.reg(usp)
		fetcher=self._create_fetcher(config)
		handler=CrawlHandler()
		c={'USP':usp,'FETCHER':fetcher,'HANDLER':handler,'CPM':cpm,'CONFIG':config}

		
		return c

	def _create_usp(self,config):
		try:
			startFile=config['START_URL_FILES']
		except KeyError:
			startFile=None
		#taskName=config['TASK_NAME']
		dataDir=config['DATA_DIR']
		usp=BaseURLSupplier(START_URL_FILES=startFile,DATA_DIR=dataDir)
		return usp
		
	def _create_fetcher(self,config):
		fetcher=Fetcher()
		return fetcher

	def _create_pm(self,components,crawler):
		usp=components['USP']
		config=components['CONFIG']
		accessParts={'USP':usp,'CONFIG':config,'CRAWLER':crawler}
		pm=ProcessorManager(accessParts,config['PROCESSORS'])
		return pm


	def __create_processors(self,pm,handler):
		ps=pm.create_head_processors()
		for p in ps:
			handler.reg_head_processor(p)
		
		ps=pm.create_content_processors()
		for p in ps:
			handler.reg_content_processor(p)

		ps=pm.create_cmd_processors()
		for p in ps:
			handler.reg_cmd_processor(p)

		ps=pm.create_error_processors()
		for p in ps:
			handler.reg_error_processor(p)

AFC=AnoleFactory()
